package org.lmaor.menu.mg;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.lmaor.menu.MenuListener;
import org.lmaor.menu.MenuManage;
import org.lmaor.menu.entry.Menu;

public class MenuManageImpl<T> implements MenuManage<T> {
	private MenuItem<T> root = new MenuItem<T>(this,true);
	private Map<String, Menu<T>> indexed = new ConcurrentHashMap<String, Menu<T>>(32);
	private List<MenuListener<T>> menuListeners = new ArrayList<MenuListener<T>>();
	@Override
	public Menu<T> create(String path) {
		if(existIndexed(path)){
			return get(path);
		}
		MenuItem<T> item = root.create();
		if(!root.add(path, item)){
			item = (MenuItem<T>) root.get(path);
			if(item!=null){
				addIndexed(item);
			}
		}
		return item;
	}

	@Override
	public Menu<T> create(String path, T value) {
		return create(path).setValue(value);
	}
	
	@Override
	public Menu<T> create(String path, String name, T value) {
		return create(path, value).setName(name);
	}
	@Override
	public Menu<T> get(String path) {
		
//		return root.get(path);
		return getIndexed(path);
	}

	@Override
	public List<Menu<T>> findMenus(String path) {
 		Menu<T> menu  = get(path);
 		if(menu == null){
 			return new ArrayList<Menu<T>>(0);
 		}else{
 			return menu.getAllChildMenus();
 		}
	}
	
	@Override
	public Menu<T> remove(String path) {
		
		return root.remove(path);
	}
	protected void addIndexed(Menu<T> menu){
		indexed.put(menu.getPath(), menu);
	}
	protected void removeIndexed(Menu<T> menu){
		indexed.remove(menu.getPath());
		List<String> paths = menu.getAllChildMenuPaths();
		for (String path : paths) {
			indexed.remove(path);
		}
	}
	protected Menu<T> getIndexed(String path){
		return indexed.get(path);
	}
	protected boolean existIndexed(String path){
		return indexed.containsKey(path);
	}
	@Override
	public T getValue(String path) {
		Menu<T> menu = get(path);
		return menu==null?null:menu.getValue();
	}

	@Override
	public boolean exist(String path) {
		
		return existIndexed(path);
	}
	@Override
	public void addMenuListener(MenuListener<T> menuListener) {
		
		menuListeners.add(menuListener);
	}
	protected void addListener(Menu<T> menu){
		for (MenuListener<T> menuListener : menuListeners) {
			menuListener.addListener(menu, this);
		}
	}
	protected void getListener(Menu<T> menu){
		for (MenuListener<T> menuListener : menuListeners) {
			menuListener.getListener(menu, this);
		}
	}
	/** 成功删除后会调用
	 * 
	 * @param menu
	 */
	protected void removeListener(Menu<T> menu){
		for (MenuListener<T> menuListener : menuListeners) {
			menuListener.removeListener(menu, this);
		}
	}
	@SuppressWarnings("hiding")
	protected class MenuItem<T> extends Menu<T> {
		MenuManageImpl<T> mg = null;

		public MenuItem(MenuManageImpl<T> mg,boolean autoDir) {
			this.mg = mg;
			this.setAutoDir(autoDir);
		}
		public MenuItem(MenuManageImpl<T> mg) {
			this.mg = mg;
		}
		@Override
		protected void addListener(Menu<T> menu) {
			mg.addIndexed(menu);
			mg.addListener(menu);
		}
		@Override
		protected void removeListener(Menu<T> menu) {
			mg.removeIndexed(menu);
			mg.removeListener(menu);
		}
		@Override
		protected void getListener(Menu<T> menu) {
			mg.getListener(menu);
		}
		@Override
		public MenuItem<T> create() {
			return new MenuItem<T>(mg);
		}
	}

	
}
